/* Version definitions */
#undef NTDDI_VERSION
#define NTDDI_VERSION NTDDI_WS03SP1
#undef _WIN32_WINNT
#define _WIN32_WINNT _WIN32_WINNT_WS03

#include <ntifs.h>
#include <ndk/ntndk.h>

#define C_ASSERT_FIELD(Type, Offset, MemberType, MemberName) \
    C_ASSERT(FIELD_OFFSET(Type, MemberName) == Offset); \
    C_ASSERT(FIELD_SIZE(Type, MemberName) == sizeof(MemberType));

/* KTHREAD */
C_ASSERT_FIELD(KTHREAD, 0x000, DISPATCHER_HEADER, Header)
C_ASSERT_FIELD(KTHREAD, 0x010, LIST_ENTRY, MutantListHead)
C_ASSERT_FIELD(KTHREAD, 0x018, PVOID, InitialStack)
C_ASSERT_FIELD(KTHREAD, 0x01C, PVOID, StackLimit)
C_ASSERT_FIELD(KTHREAD, 0x020, PVOID, KernelStack)
C_ASSERT_FIELD(KTHREAD, 0x024, ULONG, ThreadLock)
C_ASSERT_FIELD(KTHREAD, 0x028, KAPC_STATE, ApcState)
C_ASSERT_FIELD(KTHREAD, 0x028, UCHAR[23], ApcStateFill)
C_ASSERT_FIELD(KTHREAD, 0x03F, UCHAR, ApcQueueable)
C_ASSERT_FIELD(KTHREAD, 0x040, UCHAR, NextProcessor)
C_ASSERT_FIELD(KTHREAD, 0x041, UCHAR, DeferredProcessor)
C_ASSERT_FIELD(KTHREAD, 0x042, UCHAR, AdjustReason)
C_ASSERT_FIELD(KTHREAD, 0x043, CHAR, AdjustIncrement)
C_ASSERT_FIELD(KTHREAD, 0x044, ULONG, ApcQueueLock)
C_ASSERT_FIELD(KTHREAD, 0x048, ULONG, ContextSwitches)
C_ASSERT_FIELD(KTHREAD, 0x04C, UCHAR, State)
C_ASSERT_FIELD(KTHREAD, 0x04D, UCHAR, NpxState)
C_ASSERT_FIELD(KTHREAD, 0x04E, UCHAR, WaitIrql)
C_ASSERT_FIELD(KTHREAD, 0x04F, CHAR, WaitMode)
C_ASSERT_FIELD(KTHREAD, 0x050, LONG, WaitStatus)
C_ASSERT_FIELD(KTHREAD, 0x054, PKWAIT_BLOCK, WaitBlockList)
C_ASSERT_FIELD(KTHREAD, 0x054, PKGATE, GateObject)
C_ASSERT_FIELD(KTHREAD, 0x058, UCHAR, Alertable)
C_ASSERT_FIELD(KTHREAD, 0x059, UCHAR, WaitNext)
C_ASSERT_FIELD(KTHREAD, 0x05A, UCHAR, WaitReason)
C_ASSERT_FIELD(KTHREAD, 0x05B, CHAR, Priority)
C_ASSERT_FIELD(KTHREAD, 0x05C, UCHAR, EnableStackSwap)
C_ASSERT_FIELD(KTHREAD, 0x05D, UCHAR, SwapBusy)
C_ASSERT_FIELD(KTHREAD, 0x05E, UCHAR[2], Alerted)
C_ASSERT_FIELD(KTHREAD, 0x060, LIST_ENTRY, WaitListEntry)
C_ASSERT_FIELD(KTHREAD, 0x060, SINGLE_LIST_ENTRY, SwapListEntry)
C_ASSERT_FIELD(KTHREAD, 0x068, KQUEUE*, Queue)
C_ASSERT_FIELD(KTHREAD, 0x06C, ULONG, WaitTime)
C_ASSERT_FIELD(KTHREAD, 0x070, SHORT, KernelApcDisable)
C_ASSERT_FIELD(KTHREAD, 0x072, SHORT, SpecialApcDisable)
C_ASSERT_FIELD(KTHREAD, 0x070, ULONG, CombinedApcDisable)
C_ASSERT_FIELD(KTHREAD, 0x074, PVOID, Teb)
C_ASSERT_FIELD(KTHREAD, 0x078, KTIMER, Timer)
C_ASSERT_FIELD(KTHREAD, 0x078, UCHAR[40], TimerFill)
C_ASSERT_FIELD(KTHREAD, 0x0A0, LONG, ThreadFlags)
C_ASSERT_FIELD(KTHREAD, 0x0A8, KWAIT_BLOCK[4], WaitBlock)
C_ASSERT_FIELD(KTHREAD, 0x0A8, UCHAR[23], WaitBlockFill0)
C_ASSERT_FIELD(KTHREAD, 0x0BF, UCHAR, SystemAffinityActive)
C_ASSERT_FIELD(KTHREAD, 0x0A8, UCHAR[47], WaitBlockFill1)
C_ASSERT_FIELD(KTHREAD, 0x0D7, CHAR, PreviousMode)
C_ASSERT_FIELD(KTHREAD, 0x0A8, UCHAR[71], WaitBlockFill2)
C_ASSERT_FIELD(KTHREAD, 0x0EF, UCHAR, ResourceIndex)
C_ASSERT_FIELD(KTHREAD, 0x0A8, UCHAR[95], WaitBlockFill3)
C_ASSERT_FIELD(KTHREAD, 0x107, UCHAR, LargeStack)
C_ASSERT_FIELD(KTHREAD, 0x108, LIST_ENTRY, QueueListEntry)
C_ASSERT_FIELD(KTHREAD, 0x110, PKTRAP_FRAME, TrapFrame)
C_ASSERT_FIELD(KTHREAD, 0x114, PVOID, CallbackStack)
C_ASSERT_FIELD(KTHREAD, 0x118, PVOID, ServiceTable)
C_ASSERT_FIELD(KTHREAD, 0x11C, UCHAR, ApcStateIndex)
C_ASSERT_FIELD(KTHREAD, 0x11D, UCHAR, IdealProcessor)
C_ASSERT_FIELD(KTHREAD, 0x11E, UCHAR, Preempted)
C_ASSERT_FIELD(KTHREAD, 0x11F, UCHAR, ProcessReadyQueue)
C_ASSERT_FIELD(KTHREAD, 0x120, UCHAR, KernelStackResident)
C_ASSERT_FIELD(KTHREAD, 0x121, CHAR, BasePriority)
C_ASSERT_FIELD(KTHREAD, 0x122, CHAR, PriorityDecrement)
C_ASSERT_FIELD(KTHREAD, 0x123, CHAR, Saturation)
C_ASSERT_FIELD(KTHREAD, 0x124, ULONG, UserAffinity)
C_ASSERT_FIELD(KTHREAD, 0x128, PKPROCESS, Process)
C_ASSERT_FIELD(KTHREAD, 0x12C, ULONG, Affinity)
C_ASSERT_FIELD(KTHREAD, 0x130, PKAPC_STATE[2], ApcStatePointer)
C_ASSERT_FIELD(KTHREAD, 0x138, KAPC_STATE, SavedApcState)
C_ASSERT_FIELD(KTHREAD, 0x138, UCHAR[23], SavedApcStateFill)
C_ASSERT_FIELD(KTHREAD, 0x14F, CHAR, FreezeCount)
C_ASSERT_FIELD(KTHREAD, 0x150, CHAR, SuspendCount)
C_ASSERT_FIELD(KTHREAD, 0x151, UCHAR, UserIdealProcessor)
C_ASSERT_FIELD(KTHREAD, 0x152, UCHAR, CalloutActive)
C_ASSERT_FIELD(KTHREAD, 0x153, UCHAR, Iopl)

/* TEB */
C_ASSERT_FIELD(TEB, 0x000, NT_TIB, NtTib)
C_ASSERT_FIELD(TEB, 0x01C, PVOID, EnvironmentPointer)
C_ASSERT_FIELD(TEB, 0x020, CLIENT_ID, ClientId)
C_ASSERT_FIELD(TEB, 0x028, PVOID, ActiveRpcHandle)
C_ASSERT_FIELD(TEB, 0x02C, PVOID, ThreadLocalStoragePointer)
C_ASSERT_FIELD(TEB, 0x030, PPEB, ProcessEnvironmentBlock)
C_ASSERT_FIELD(TEB, 0x034, ULONG, LastErrorValue)
C_ASSERT_FIELD(TEB, 0x038, ULONG, CountOfOwnedCriticalSections)
C_ASSERT_FIELD(TEB, 0x03C, PVOID, CsrClientThread)
C_ASSERT_FIELD(TEB, 0x040, PVOID, Win32ThreadInfo)
C_ASSERT_FIELD(TEB, 0x044, ULONG[26], User32Reserved)
C_ASSERT_FIELD(TEB, 0x0AC, ULONG[5], UserReserved)
C_ASSERT_FIELD(TEB, 0x0C0, PVOID, WOW32Reserved)
C_ASSERT_FIELD(TEB, 0x0C4, ULONG, CurrentLocale)
C_ASSERT_FIELD(TEB, 0x0C8, ULONG, FpSoftwareStatusRegister)
C_ASSERT_FIELD(TEB, 0x0CC, PVOID[54], SystemReserved1)
C_ASSERT_FIELD(TEB, 0x1A4, LONG, ExceptionCode)
C_ASSERT_FIELD(TEB, 0x1A8, PACTIVATION_CONTEXT_STACK, ActivationContextStackPointer)
C_ASSERT_FIELD(TEB, 0x1AC, UCHAR[40], SpareBytes1)
C_ASSERT_FIELD(TEB, 0x1D4, GDI_TEB_BATCH, GdiTebBatch)
C_ASSERT_FIELD(TEB, 0x6B4, CLIENT_ID, RealClientId)
C_ASSERT_FIELD(TEB, 0x6BC, PVOID, GdiCachedProcessHandle)
C_ASSERT_FIELD(TEB, 0x6C0, ULONG, GdiClientPID)
C_ASSERT_FIELD(TEB, 0x6C4, ULONG, GdiClientTID)
C_ASSERT_FIELD(TEB, 0x6C8, PVOID, GdiThreadLocalInfo)
C_ASSERT_FIELD(TEB, 0x6CC, ULONG[62], Win32ClientInfo)
C_ASSERT_FIELD(TEB, 0x7C4, PVOID[233], glDispatchTable)
C_ASSERT_FIELD(TEB, 0xB68, ULONG[29], glReserved1)
C_ASSERT_FIELD(TEB, 0xBDC, PVOID, glReserved2)
C_ASSERT_FIELD(TEB, 0xBE0, PVOID, glSectionInfo)
C_ASSERT_FIELD(TEB, 0xBE4, PVOID, glSection)
C_ASSERT_FIELD(TEB, 0xBE8, PVOID, glTable)
C_ASSERT_FIELD(TEB, 0xBEC, PVOID, glCurrentRC)
C_ASSERT_FIELD(TEB, 0xBF0, PVOID, glContext)
C_ASSERT_FIELD(TEB, 0xBF4, ULONG, LastStatusValue)
C_ASSERT_FIELD(TEB, 0xBF8, UNICODE_STRING, StaticUnicodeString)
C_ASSERT_FIELD(TEB, 0xC00, WCHAR[261], StaticUnicodeBuffer)
C_ASSERT_FIELD(TEB, 0xE0C, PVOID, DeallocationStack)
C_ASSERT_FIELD(TEB, 0xE10, PVOID[64], TlsSlots)
C_ASSERT_FIELD(TEB, 0xF10, LIST_ENTRY, TlsLinks)
C_ASSERT_FIELD(TEB, 0xF18, PVOID, Vdm)
C_ASSERT_FIELD(TEB, 0xF1C, PVOID, ReservedForNtRpc)
C_ASSERT_FIELD(TEB, 0xF20, PVOID[2], DbgSsReserved)
C_ASSERT_FIELD(TEB, 0xF28, ULONG, HardErrorMode)
C_ASSERT_FIELD(TEB, 0xF2C, PVOID[14], Instrumentation)
C_ASSERT_FIELD(TEB, 0xF64, PVOID, SubProcessTag)
C_ASSERT_FIELD(TEB, 0xF68, PVOID, EtwTraceData)
C_ASSERT_FIELD(TEB, 0xF6C, PVOID, WinSockData)
C_ASSERT_FIELD(TEB, 0xF70, ULONG, GdiBatchCount)
C_ASSERT_FIELD(TEB, 0xF74, UCHAR, InDbgPrint)
C_ASSERT_FIELD(TEB, 0xF75, UCHAR, FreeStackOnTermination)
C_ASSERT_FIELD(TEB, 0xF76, UCHAR, HasFiberData)
C_ASSERT_FIELD(TEB, 0xF77, UCHAR, IdealProcessor)
C_ASSERT_FIELD(TEB, 0xF78, ULONG, GuaranteedStackBytes)
C_ASSERT_FIELD(TEB, 0xF7C, PVOID, ReservedForPerf)
C_ASSERT_FIELD(TEB, 0xF80, PVOID, ReservedForOle)
C_ASSERT_FIELD(TEB, 0xF84, ULONG, WaitingOnLoaderLock)
C_ASSERT_FIELD(TEB, 0xF88, ULONG, SparePointer1)
C_ASSERT_FIELD(TEB, 0xF8C, ULONG, SoftPatchPtr1)
C_ASSERT_FIELD(TEB, 0xF90, ULONG, SoftPatchPtr2)
C_ASSERT_FIELD(TEB, 0xF94, PVOID*, TlsExpansionSlots)
C_ASSERT_FIELD(TEB, 0xF98, ULONG, ImpersonationLocale)
C_ASSERT_FIELD(TEB, 0xF9C, ULONG, IsImpersonating)
C_ASSERT_FIELD(TEB, 0xFA0, PVOID, NlsCache)
C_ASSERT_FIELD(TEB, 0xFA4, PVOID, pShimData)
C_ASSERT_FIELD(TEB, 0xFA8, ULONG, HeapVirtualAffinity)
C_ASSERT_FIELD(TEB, 0xFAC, PVOID, CurrentTransactionHandle)
C_ASSERT_FIELD(TEB, 0xFB0, PTEB_ACTIVE_FRAME, ActiveFrame)
C_ASSERT_FIELD(TEB, 0xFB4, PVOID, FlsData)
C_ASSERT_FIELD(TEB, 0xFB8, UCHAR, SafeThunkCall)
C_ASSERT_FIELD(TEB, 0xFB9, UCHAR[3], BooleanSpare)

/* KUSER_SHARED_DATA */
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x000, ULONG, TickCountLowDeprecated)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x004, ULONG, TickCountMultiplier)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x008, KSYSTEM_TIME, InterruptTime)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x014, KSYSTEM_TIME, SystemTime)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x020, KSYSTEM_TIME, TimeZoneBias)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x02C, USHORT, ImageNumberLow)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x02E, USHORT, ImageNumberHigh)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x030, WCHAR[260], NtSystemRoot)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x238, ULONG, MaxStackTraceDepth)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x23C, ULONG, CryptoExponent)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x240, ULONG, TimeZoneId)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x244, ULONG, LargePageMinimum)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x248, ULONG[7], Reserved2)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x264, NT_PRODUCT_TYPE, NtProductType)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x268, BOOLEAN, ProductTypeIsValid)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x26C, ULONG, NtMajorVersion)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x270, ULONG, NtMinorVersion)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x274, BOOLEAN[64], ProcessorFeatures)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2B4, ULONG, Reserved1)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2B8, ULONG, Reserved3)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2BC, ULONG, TimeSlip)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2C0, ALTERNATIVE_ARCHITECTURE_TYPE, AlternativeArchitecture)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2C8, LARGE_INTEGER, SystemExpirationDate)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2D0, ULONG, SuiteMask)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2D4, BOOLEAN, KdDebuggerEnabled)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2D5, UCHAR, MitigationPolicies) // NXSupportPolicy
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2D8, ULONG, ActiveConsoleId)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2DC, ULONG, DismountCount)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2E0, ULONG, ComPlusPackage)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2E4, ULONG, LastSystemRITEventTickCount)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2E8, ULONG, NumberOfPhysicalPages)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2EC, BOOLEAN, SafeBootMode)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2F0, ULONG, TraceLogging)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x2F8, ULONGLONG, TestRetInstruction)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x300, ULONG, SystemCall)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x304, ULONG, SystemCallReturn)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x320, KSYSTEM_TIME, TickCount)
C_ASSERT_FIELD(KUSER_SHARED_DATA, 0x320, ULONGLONG, TickCountQuad)
